package model

import (
	"errors"
	"fmt"
	"time"
	"tools-api/src/common/db/database"
	"xorm.io/xorm"
)

// Book 账本
type Book struct {
	Id         int64     `json:"id"`
	Uuid       string    `json:"-"`
	Name       string    `json:"name"`
	MonthStart int       `json:"month_start"`
	Current    bool      `json:"current" xorm:"tinyint(1)"`
	CreatedAt  time.Time `xorm:"created" json:"-"`
	ModifiedAt time.Time `xorm:"updated" json:"-"`
	DeleteMark int       `xorm:"delete_mark" json:"-"`
}
type BookResult struct {
	Id         int64   `json:"id"`
	Name       string  `json:"name"`
	MonthStart int     `json:"month_start"`
	Current    bool    `json:"current" xorm:"tinyint(1)"`
	Count      int     `json:"count"` // 有多少笔
	Payout     float64 `json:"payout"`
	Income     float64 `json:"income"`
}

// CopyFromDefault 新建用户，复制默认账本
func (Book) CopyFromDefault(uuid string) error {
	sql := fmt.Sprintf("insert into book (uuid, `name`, month_start) select '%s', `name`, month_start from book where uuid= '0' and delete_mark = 0", uuid)
	res, err := database.JCJEngine.Exec(sql)
	if err != nil {
		return err
	}
	affectedRows, _ := res.RowsAffected()
	if affectedRows == 0 {
		return errors.New("拷贝失败")
	}
	return nil
}

func (b Book) Create() Book {
	_, _ = database.JCJEngine.Insert(&b)
	return b
}

func (b Book) Update() (Book, error) {
	_, err := database.JCJEngine.Where("id=? and uuid=?", b.Id, b.Uuid).Update(&b)
	return b, err
}

// Delete 单个删除(非当前账本才可以删除)
func (b Book) Delete(session *xorm.Session, uuid string, id int64) error {
	b.DeleteMark = 1
	rows, err := session.Where("id=? and uuid=? and current=0", id, uuid).Update(&b)
	if err != nil {
		return err
	}
	if rows == 0 {
		return errors.New("删除失败")
	}
	return nil
}

func (b Book) GetCurrent(uuid string) Book {
	_, _ = database.JCJEngine.Where("uuid= ? and delete_mark=0 and current=1", uuid).Get(&b)
	return b
}

// GetList 包括 笔数，总支出，总收入
func (Book) GetList(uuid string) []BookResult {
	list := make([]BookResult, 0)
	_ = database.JCJEngine.Table(Book{}).Alias("b").
		Join("LEFT", []string{"book_detail", "d"}, "d.book_id = b.id and d.delete_mark = 0").
		Select("b.id, b.name, b.month_start, b.current, count(d.id) as count, sum(case when d.type = 1 then d.money else 0 end) as payout, sum(case when d.type = 2 then d.money else 0 end) as income").
		Where("b.uuid=? and b.delete_mark=0", uuid).
		GroupBy("b.id, b.name, b.month_start, b.current").
		Find(&list)
	return list
}

// BookSetCurrent 设置当前账本
func (Book) BookSetCurrent(uuid string, id int64) error {
	sql := fmt.Sprintf("UPDATE book SET current = case id when %d then 1 else 0 end where uuid= '%s'", id, uuid)
	res, err := database.JCJEngine.Exec(sql)
	if err != nil {
		return err
	}
	affectedRows, _ := res.RowsAffected()
	if affectedRows == 0 {
		return errors.New("设置失败")
	}
	return nil
}
